package cc.rengu.redp.flowable.controller;

import cc.rengu.redp.common.annotation.Log;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.domain.RedpResponse;
import cc.rengu.redp.common.utils.RedpUtil;
import cc.rengu.redp.flowable.bizmodel.BizModelBuilder;
import cc.rengu.redp.flowable.service.ProcessService;
import com.alibaba.fastjson.JSON;
import com.google.common.io.ByteStreams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/process")
public class ProcessController {

    @Autowired
    private BizModelBuilder bizModelBuilder;

    @Autowired
    private ProcessService processService;

    @Log("获取可用的申请列表")
    @GetMapping("/availablepro")
    public RedpResponse getAvailableProcess(String userId) {
        try {
            return RedpResponse.getInstance().data(processService.getAvailableProcess(userId)).success();
        } catch (Exception e) {
            String message = "获取可用的申请列表失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @Log("获取待办事项")
    @GetMapping("/waitingtodo")
    public RedpResponse getWaitingToDo(String queryText, QueryRequest queryRequest) {
        try {
            Map<String, Object> data = processService.getWaitingToDo(RedpUtil.getCurrentUser().getUsername(), queryText, queryRequest);
            return RedpResponse.getInstance().data(data).success();
        } catch (Exception e) {
            String message = "获取待办事项失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @Log("获取业务数据")
    @GetMapping("flowData")
    public RedpResponse getFlowData(String procInstId) {
        try {
            return RedpResponse.getInstance().data(processService.getFlowData(procInstId)).success();
        } catch (Exception e) {
            String message = "获取业务数据失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @Log("获取可选分支列表")
    @GetMapping("/nexttodo")
    public Map<String, Object> getNextToDo(String taskId) {
        try {
            return RedpResponse.getInstance().data(processService.getNextToDo(taskId)).success();
        } catch (Exception e) {
            String message = "获取可选分支列表失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @Log("填写申请单启动流程")
    @PostMapping("launch")
    public RedpResponse launchForm(String flowData, String processDefinitionKey, String applicant, String nextAssignee) {
        try {
            bizModelBuilder.checkJsonData(JSON.parseObject(flowData));
            processService.launch(flowData, processDefinitionKey, applicant, nextAssignee);
        } catch (Exception e) {
            String message = "启动流程失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message + "：" + e.getMessage());
        }
        return RedpResponse.getInstance().success().message("启动流程成功");
    }

    @Log("选择分支完成任务")
    @PostMapping("complete")
    public RedpResponse completeTask(String taskId,
                                     String flowStatus,
                                     String procInstId,
                                     String comment,
                                     String flowData,
                                     String applicant,
                                     String nextAssignee) {
        try {
            bizModelBuilder.checkJsonData(JSON.parseObject(flowData));
            processService.completeTask(taskId, flowStatus, procInstId, comment, flowData, applicant, nextAssignee);
        } catch (Exception e) {
            String message = "任务单提交失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message + "：" + e.getMessage());
        }
        return RedpResponse.getInstance().success().message("任务单提交成功");
    }

    // 查看之前经过的节点
    @Log("获取历史路径")
    @GetMapping("hisactivities")
    public Map<String, Object> getHisActivities(String procInstId) {
        return processService.getHisActivities(procInstId);
    }

    @Log("获取指定分支指向节点的候选人群")
    @GetMapping("candidateUsers")
    public Map<String, Object> getCandidateUsersBySeqIdAndTaskId(String seqId, String taskId) {
        return processService.getCandidateUsersPrevious(seqId, taskId);
    }

    @Log("获取指定分支指向节点的候选人群")
    @GetMapping("launch/candidateUsers")
    public Map<String, Object> getCandidateUsersByProcDefId(String procDefKey) {
        return processService.getCandidateUsersPrevious(procDefKey);
    }

    @Log("任务单列表查询")
    @GetMapping("getAllProcInstances")
    public Map<String, Object> getAllProcInstances(String procDefName, String applicant, String procStatus, QueryRequest queryRequest) {
        return processService.getAllProcInstances(procDefName, applicant, procStatus, queryRequest);
    }

    @Log("查看发布流程图")
    public ByteStreams getProcGraphic(String procDefId) {

        return null;
    }

    @Log("强制终止流程")
    @DeleteMapping
    public RedpResponse terminateProcess(String procInstId) {
        try {
            processService.terminateProcess(procInstId);
        } catch (Exception e) {
            String message = "强制终止流程失败";
            return RedpResponse.getInstance().failure().message(message + "：" + e.getMessage());
        }
        return RedpResponse.getInstance().success().message("强制终止流程成功");
    }

    @Log("获取在途申请单")
    @GetMapping("/inTransitProcess")
    public RedpResponse getInTransitProcess(String queryText, QueryRequest queryRequest) {
        try {
            Map<String, Object> data = processService.getInTransitProcess(RedpUtil.getCurrentUser().getUsername(), queryText, queryRequest);
            return RedpResponse.getInstance().data(data).success();
        } catch (Exception e) {
            String message = "获取在途申请单失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    /*
     * 查询最近结束任务单
     * */
    @Log("最近结束任务单")
    @GetMapping("/latelyClosedProcess")
    public RedpResponse getLatelyClosedProcess(String queryText, QueryRequest queryRequest) {
        try {
            Map<String, Object> data = processService.getLatelyClosedProcess(RedpUtil.getCurrentUser().getUsername(), queryText, queryRequest);
            return RedpResponse.getInstance().data(data).success();
        } catch (Exception e) {
            String message = "获取最近结束任务单失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }
}
